package com.haixee.parkdemo.gateway.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.haixee.parkdemo.common.entity.AuthData;
import com.haixee.parkdemo.common.exception.BusinessException;
import com.haixee.parkdemo.common.response.CommonResEnum;
import com.haixee.parkdemo.common.response.ResResult;
import com.haixee.parkdemo.gateway.client.AuthService;
import com.haixee.parkdemo.gateway.constants.WebConstants;
import com.haixee.parkdemo.gateway.utils.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author windtreeland
 * 2021/5/10 16:13
 */
@Slf4j
//@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private AuthService authService;

//    @Override
//    public GatewayFilter apply(Object config) {
//
//        InnerFilter innerFilter = new InnerFilter();
//        innerFilter.setAuthService(authService);
//
//        return innerFilter;
//    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取 token
        HttpHeaders headers = exchange.getRequest().getHeaders();
        String token = RequestUtil.getValueFromHeader(headers, WebConstants.HEADER_TOKEN);

        // 2. 解析出 uid
        String uidVar = null;
        String authDataVar = null;


        HttpMethod method = exchange.getRequest().getMethod();
        Byte methodCode = null;
        if (method == HttpMethod.GET) {
            methodCode = 1;
        } else if (method == HttpMethod.POST) {
            methodCode = 2;
        }

        String path = exchange.getRequest().getURI().getPath();
        ResResult<AuthData> resResult = authService.getAuth(token, methodCode, path);

        if (resResult.getCode() != 0) {
            throw new BusinessException(HttpStatus.OK, resResult.getCode(), resResult.getMsg());
        }

        if (resResult.getData() == null) {
            throw new BusinessException(HttpStatus.OK, CommonResEnum.TOKEN_ERROR);
        }

        AuthData data = resResult.getData();

        if (!Boolean.TRUE.equals(data.getAuth())) {
            throw new BusinessException(HttpStatus.OK, CommonResEnum.PERMISSION_DENIED);
        }

        if (data.getUid() != null) {
            uidVar = data.getUid().toString();
            exchange.getAttributes().put(WebConstants.HEADER_UID, uidVar);
        }


        ObjectMapper objectMapper = new ObjectMapper();
        try {
            authDataVar = objectMapper.writeValueAsString(data);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        // 将uid放在请求头给微服务提供权限信息
        ServerHttpRequest request = exchange.getRequest().mutate()
                .header(WebConstants.HEADER_UID, uidVar)
                .header(WebConstants.AUTH_DATA, authDataVar)
                .build();
        return chain.filter(exchange.mutate().request(request).build());
    }

    @Override
    public int getOrder() {
        return -5;
    }

}
